<?php
function validate(&$check, $param=null){
	$pattern = "/\||;|&|%|\r|\n|\\\$|'|\"|\'|\\\"|<|>|\\\\/i";//|\(|\)|@

	if (is_null($param)) {
		$param = array(
			'auction_id'=>'int','goods_sku'=>'string','shipping_area_id'=>'int','address_id'=>'int','order_amount'=>'float','country'=>'int','province'=>'string',
			'city'=>'string','add_province'=>'int','add_city'=>'int','sku_sn'=>'string','ext_attr_info'=>'string','price'=>'string','choose_num'=>'int','action'=>'string',
			'checknumber'=>'string','pre_sku_sn'=>'string','goods_sn'=>'string','goods_num'=>'int','goods_arr'=>'string','extension_code'=>'string','type'=>'string',
			'user_id'=>'email','suit_code'=>'string','goods_sns'=>'string','suit_skus'=>'string','cat_id_str'=>'string','cat_id'=>'int','cid'=>'int','news_id'=>'int',
			'actives_id'=>'int','aid'=>'int','key_search'=>'stringEXT','order_by'=>'string','color_code'=>'string','order_sn'=>'string','size_code'=>'string',
			'need_bill'=>'int','inv_content'=>'string','inv_payee'=>'string','remark'=>'text','stairs_fee'=>'float','fix_fee'=>'float','vouchers'=>'string',
			'coupon'=>'string','integral'=>'int','user_money'=>'float','best_time'=>'string','type_code'=>'string','brand_code'=>'string','mode'=>'string',
			'order_code'=>'string','orderby'=>'int','theme_code'=>'string','order_id'=>'int','color'=>'string','ccard'=>'string','size'=>'string','show'=>'int',
			'ext_attr'=>'string','ext_value'=>'string','shop_price'=>'string','series_name'=>'string','tem_name'=>'string','fashion_name'=>'string','ajax_url'=>'url',
			'brand'=>'string','series'=>'string','meterial'=>'string','discount'=>'','username'=>'email','id_value'=>'string','order_goods_id'=>'string',
			'comment_type'=>'int','comment_position'=>'int','comment_type'=>'string','cat_name_str'=>'string','key_search_str'=>'string','send_email'=>'email',
			'telephone'=>'string','tid'=>'int','email'=>'email','nickname'=>'string','old_password'=>'ignore','new_password'=>'ignore','password'=>'ignore','is_active'=>'int','mobile'=>'string','parent_id'=>'email',
			'tel'=>'tel','phone'=>'string','alias'=>'text','user_name'=>'email','id_number'=>'sring','consignee'=>'text','default_address'=>'int','c'=>'string','newContent'=>'ignore','tpl_file'=>'ignore'
		);
	}

	foreach ($check as $key=>$val) {
		if (isset($param[$key])) {
			$error = true;
			switch($param[$key]){
				case 'int':
					$error = numeric($val);
					break;
				case 'float':
					$error = decimal($val);
					break;
				case 'text':
					$error = false;
					break;
				case 'ignore':
					$error = true;
					break;
				case 'string':
					$error = alphaNumeric($val);
					break;
				case 'stringEXT':
					$error = alphaNumericExt($val);
					break;
				case 'email':
					$error = email($val);
					break;
				case 'url':
					$error = url($val);
					break;
				case 'tel':
					$error = phone($val);
					break;
			}

			if (!$error) {
				if (preg_match($pattern, $val, $match)) {
					$val = preg_replace($pattern, '', $val);
				}
				$check[$key] = $val;
				switch($param[$key]){
					case 'int':
						$check[$key] = intval($val);
						break;
					case 'float':
						$check[$key] = floatval($val);
						break;
				}
			}
		} else {
			if (is_array($val)) {
				foreach($val as $k=>$v){
					unset($val[$k]);
					if(!is_array($v)){
						if (preg_match($pattern, $v, $match)) {
							$v = preg_replace($pattern, '', $v);
						}
						$val[$k] = $v;
					}
				}
			} else {
				if (preg_match($pattern, $val, $match)) {
					$val = preg_replace($pattern, '', $val);
				}
				$check[$key] = $val;
			}
		}
	}
}

function alphaNumeric($check) {
	if (empty($check) && $check != '0') {
		return false;
	}
	$regex = '/^[\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}\;]+$/mu';
	return _check($regex, $check);
}

function alphaNumericExt($check) {
	if (empty($check) && $check != '0') {
		return false;
	}
	$regex = '/^[\p{Ll}\p{Lm}\p{Lo}\p{Lt}\p{Lu}\p{Nd}\;\=\+]+$/mu';
	return _check($regex, $check);
}

function _date($check, $format = 'ymd', $regex = null) {
	if (!is_null($regex)) {
		return _check($regex, $check);
	}

	$regex['dmy'] = '%^(?:(?:31(\\/|-|\\.|\\x20)(?:0?[13578]|1[02]))\\1|(?:(?:29|30)(\\/|-|\\.|\\x20)(?:0?[1,3-9]|1[0-2])\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:29(\\/|-|\\.|\\x20)0?2\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:0?[1-9]|1\\d|2[0-8])(\\/|-|\\.|\\x20)(?:(?:0?[1-9])|(?:1[0-2]))\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%';
	$regex['mdy'] = '%^(?:(?:(?:0?[13578]|1[02])(\\/|-|\\.|\\x20)31)\\1|(?:(?:0?[13-9]|1[0-2])(\\/|-|\\.|\\x20)(?:29|30)\\2))(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$|^(?:0?2(\\/|-|\\.|\\x20)29\\3(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00))))$|^(?:(?:0?[1-9])|(?:1[0-2]))(\\/|-|\\.|\\x20)(?:0?[1-9]|1\\d|2[0-8])\\4(?:(?:1[6-9]|[2-9]\\d)?\\d{2})$%';
	$regex['ymd'] = '%^(?:(?:(?:(?:(?:1[6-9]|[2-9]\\d)?(?:0[48]|[2468][048]|[13579][26])|(?:(?:16|[2468][048]|[3579][26])00)))(\\/|-|\\.|\\x20)(?:0?2\\1(?:29)))|(?:(?:(?:1[6-9]|[2-9]\\d)?\\d{2})(\\/|-|\\.|\\x20)(?:(?:(?:0?[13578]|1[02])\\2(?:31))|(?:(?:0?[1,3-9]|1[0-2])\\2(29|30))|(?:(?:0?[1-9])|(?:1[0-2]))\\2(?:0?[1-9]|1\\d|2[0-8]))))$%';
	$regex['dMy'] = '/^((31(?!\\ (Feb(ruary)?|Apr(il)?|June?|(Sep(?=\\b|t)t?|Nov)(ember)?)))|((30|29)(?!\\ Feb(ruary)?))|(29(?=\\ Feb(ruary)?\\ (((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))|(0?[1-9])|1\\d|2[0-8])\\ (Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)\\ ((1[6-9]|[2-9]\\d)\\d{2})$/';
	$regex['Mdy'] = '/^(?:(((Jan(uary)?|Ma(r(ch)?|y)|Jul(y)?|Aug(ust)?|Oct(ober)?|Dec(ember)?)\\ 31)|((Jan(uary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sept|Nov|Dec)(ember)?)\\ (0?[1-9]|([12]\\d)|30))|(Feb(ruary)?\\ (0?[1-9]|1\\d|2[0-8]|(29(?=,?\\ ((1[6-9]|[2-9]\\d)(0[48]|[2468][048]|[13579][26])|((16|[2468][048]|[3579][26])00)))))))\\,?\\ ((1[6-9]|[2-9]\\d)\\d{2}))$/';
	$regex['My'] = '%^(Jan(uary)?|Feb(ruary)?|Ma(r(ch)?|y)|Apr(il)?|Ju((ly?)|(ne?))|Aug(ust)?|Oct(ober)?|(Sep(?=\\b|t)t?|Nov|Dec)(ember)?)[ /]((1[6-9]|[2-9]\\d)\\d{2})$%';
	$regex['my'] = '%^(((0[123456789]|10|11|12)([- /.])(([1][9][0-9][0-9])|([2][0-9][0-9][0-9]))))$%';

	$format = (is_array($format)) ? array_values($format) : array($format);
	foreach ($format as $key) {
		$regex = $regex[$key];

		if (_check($regex, $check) === true) {
			return true;
		}
	}
	return false;
}

function _time($check) {
	$regex = '%^((0?[1-9]|1[012])(:[0-5]\d){0,2}([AP]M|[ap]m))$|^([01]\d|2[0-3])(:[0-5]\d){0,2}$%';
	return _check($regex, $check);
}

function boolean($check) {
	$booleanList = array(0, 1, '0', '1', true, false);
	return in_array($check, $booleanList, true);
}

function decimal($check, $places = null, $regex = null) {
	if (is_null($regex)) {
		if (is_null($places)) {
			$regex = '/^[-+]?[0-9]*\\.{1}[0-9]+(?:[eE][-+]?[0-9]+)?$/';
		} else {
			$regex = '/^[-+]?[0-9]*\\.{1}[0-9]{'.$places.'}$/';
		}
	}
	return _check($regex, $check);
}

function email($check, $deep = false, $regex = null) {
	if (is_null($regex)) {
		$regex = '/^[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&\'*+\/=?^_`{|}~-]+)*@(?:[a-z0-9][-a-z0-9]*\.)*(?:[a-z0-9][-a-z0-9]{0,62})\.(?:(?:[a-z]{2}\.)?[a-z]{2,4}|museum|travel)$/i';
	}
	$return = _check($regex, $check);

	if ($deep === false || $deep === null) {
		return $return;
	}

	if ($return === true && preg_match('/@((?:[a-z0-9][-a-z0-9]*\.)*(?:[a-z0-9][-a-z0-9]{0,62})\.(?:(?:[a-z]{2}\.)?[a-z]{2,4}|museum|travel))$/i', $check, $regs)) {
		if (function_exists('getmxrr') && getmxrr($regs[1], $mxhosts)) {
			return true;
		}
		if (function_exists('checkdnsrr') && checkdnsrr($regs[1], 'MX')) {
			return true;
		}
		return is_array(gethostbynamel($regs[1]));
	}
	return false;
}

function equalTo($check, $comparedTo) {
	return ($check === $comparedTo);
}

function ip($check, $type = 'both') {
	$success = false;
	$type = strtolower($type);
	if ($type === 'ipv4' || $type === 'both') {
		$success |= _ipv4($check);
	}
	if ($type === 'ipv6' || $type === 'both') {
		$success |= _ipv6($check);
	}
	return $success;
}

function _ipv4($check) {
	if (function_exists('filter_var')) {
		return filter_var($check, FILTER_VALIDATE_IP, array('flags' => FILTER_FLAG_IPV4)) !== false;
	}
	$__pattern = __populateIp();
	$regex = '/^' . $__pattern['IPv4'] . '$/';
	return _check($regex, $check);
}

function _ipv6($check) {
	if (function_exists('filter_var')) {
		return filter_var($check, FILTER_VALIDATE_IP, array('flags' => FILTER_FLAG_IPV6)) !== false;
	}
	$__pattern = __populateIp();
	$regex = '/^' . $__pattern['IPv6'] . '$/';
	return _check($regex, $check);
}

function minLength($check, $min) {
	$length = mb_strlen($check);
	return ($length >= $min);
}

function maxLength($check, $max) {
	$length = mb_strlen($check);
	return ($length <= $max);
}

function money($check, $symbolPosition = 'left') {
	if ($symbolPosition == 'right') {
		$regex = '/^(?!0,?\d)(?:\d{1,3}(?:([, .])\d{3})?(?:\1\d{3})*|(?:\d+))((?!\1)[,.]\d{2})?(?<!\x{00a2})\p{Sc}?$/u';
	} else {
		$regex = '/^(?!\x{00a2})\p{Sc}?(?!0,?\d)(?:\d{1,3}(?:([, .])\d{3})?(?:\1\d{3})*|(?:\d+))((?!\1)[,.]\d{2})?$/u';
	}
	return _check($regex, $check);
}

function numeric($check) {
	return is_numeric($check);
}

function phone($check, $regex = null) {
	if (is_null($regex)) {
		$regex  = '/^(?:\+?1)?[-. ]?\\(?[2-9][0-8][0-9]\\)?[-. ]?[2-9][0-9]{2}[-. ]?[0-9]{4}$/';
	}
	return _check($regex, $check);
}

function _uuid($check) {
	$regex = '/^[a-f0-9]{8}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{4}-[a-f0-9]{12}$/i';
	return _check($regex, $check);
}

function url($check, $strict = false) {
	$validChars = '([' . preg_quote('!"$&\'()*+,-.@_:;=~') . '\/0-9a-z]|(%[0-9a-f]{2}))';
	$regex = '/^(?:(?:https?|ftps?|file|news|gopher):\/\/)' . (!empty($strict) ? '' : '?') .
		'(?::[1-9][0-9]{0,4})?' .
		'(?:\/?|\/' . $validChars . '*)?' .
		'(?:\?' . $validChars . '*)?' .
		'(?:#' . $validChars . '*)?$/i';
	return _check($regex, $check);
}

function __populateIp() {
	$pattern  = '((([0-9A-Fa-f]{1,4}:){7}(([0-9A-Fa-f]{1,4})|:))|(([0-9A-Fa-f]{1,4}:){6}';
	$pattern .= '(:|((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})';
	$pattern .= '|(:[0-9A-Fa-f]{1,4})))|(([0-9A-Fa-f]{1,4}:){5}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})';
	$pattern .= '(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)';
	$pattern .= '{4}(:[0-9A-Fa-f]{1,4}){0,1}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2}))';
	$pattern .= '{3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){3}(:[0-9A-Fa-f]{1,4}){0,2}';
	$pattern .= '((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|';
	$pattern .= '((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}';
	$pattern .= '((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2}))';
	$pattern .= '{3})?)|((:[0-9A-Fa-f]{1,4}){1,2})))|(([0-9A-Fa-f]{1,4}:)(:[0-9A-Fa-f]{1,4})';
	$pattern .= '{0,4}((:((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)';
	$pattern .= '|((:[0-9A-Fa-f]{1,4}){1,2})))|(:(:[0-9A-Fa-f]{1,4}){0,5}((:((25[0-5]|2[0-4]';
	$pattern .= '\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})?)|((:[0-9A-Fa-f]{1,4})';
	$pattern .= '{1,2})))|(((25[0-5]|2[0-4]\d|[01]?\d{1,2})(\.(25[0-5]|2[0-4]\d|[01]?\d{1,2})){3})))(%.+)?';
	$__pattern['IPv6'] = $pattern;

	$pattern = '(?:(?:25[0-5]|2[0-4][0-9]|(?:(?:1[0-9])?|[1-9]?)[0-9])\.){3}(?:25[0-5]|2[0-4][0-9]|(?:(?:1[0-9])?|[1-9]?)[0-9])';
	$__pattern['IPv4'] = $pattern;
	return $__pattern;
}

function _check($regex, $check) {
	if (preg_match($regex, $check)) {
		return true;
	} else {
		return false;
	}
}
